﻿using System;

namespace Present.Commands.Async.Actions
{
    public abstract class AsyncAction<TParameter, TResult> : IAsyncAction<TParameter, TResult>
    {
        public abstract void HandleSuccess(TResult result);

       
        void IAsyncAction.HandleSuccess(object result)
        {
            this.HandleSuccess((TResult)result);
        }


        public abstract TResult DoWork(ActionExecution<TParameter> args);

        object IAsyncAction.DoWork(ActionExecution args)
        {
            return DoWork((ActionExecution<TParameter>)args);
        }

        /// <summary>
        /// Ability to perform actions whilst still on the UI thread
        /// </summary>
        public virtual ActionExecution<TParameter> PrepareWork(TParameter parameter)
        {
            return new ActionExecution<TParameter>(parameter);
        }

        /// <summary>
        /// Ability to perform actions whilst still on the UI thread
        /// </summary>
        ActionExecution IAsyncAction.PrepareWork(object parameter)
        {
            return PrepareWork((TParameter)parameter);
        }

      
        public abstract void HandleError(Exception error);

        public virtual void HandleCancel(ActionExecution execution)
        {

        }
        
        public abstract bool CanExecute(object parameter);
        public event EventHandler<EventArgs> CanExecuteChanged;

        protected void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}